export const WAIT = 0;
export const RUNNING = 1;
export const PAUSE = 2;
export const GAMEOVER = 3;

export default {
    data: [],  //二维数组,空位0,已有1,正在下落2
    blocks: [
        [
            [[1,1,1,1]], [[1],[1],[1],[1]],  //长条
        ],
        [
            [[1,1], [1,1]],  //方块
        ],
        [
            [[1,1], [0,1],[0,1]], [[0,0,1],[1,1,1]], [[1,0], [1,0], [1,1]], [[1,1,1], [1,0,0]],    //L形
        ],
        [
            [[1,1], [1,0], [1,0]], [[1,1,1], [0,0,1]], [[0,1],[0,1],[1,1]], [[1,0,0], [1,1,1]],     //反L形
        ],
        [
            [[1,1,0], [0,1,1]], [[0,1],[1,1],[1,0]], //Z形
        ],
        [
            [[0,1,1], [1,1,0]], [[1,0],[1,1],[0,1]], //反Z形
        ],
    ],
    position: {
        top: 0,
        left: 4,
    },   //当前位置
    width: 10, 
    height: 18,
    current: 0,    //当前方块
    next: 0,   //下一方块
    shape: 0,   //当前方块形状
    score: 0,   //当前得分
    speed: 1,   //下落速度
    maxSpeed: 10,   //最大速度
    level: 1,   //当前等级
    lscore: 250,    //升级分数
    status: WAIT,   //游戏状态
    timer: null,    //计时器
    init: function() {  //初始化
        this.speed = 1
        this.score = 0
        this.timer = null
        for(let i = 0; i < this.height; i++) {
            let items = []
            for (let j = 0; j < this.width; j++) {
                items.push(0)
            }
            this.data.push(items)
        }
    },
    start: function() { //游戏开始
        if (this.status == WAIT || this.status == GAMEOVER) {
            this.speed = 1
            this.score = 0
            this.status = RUNNING
            this.current = this.generate()
            this.next = this.generate()
            for(let i = 0; i < this.height; i++) {
                for (let j = 0; j < this.width; j++) {
                    this.data[i][j] = 0
                }
            }
            this.run()
        }
    },
    pause: function() { //暂停/继续游戏
        if (this.status === PAUSE) {
            this.status = RUNNING
            this.run()
        } else if (this.status === RUNNING) {
            this.status = PAUSE
            clearInterval(this.timer)
            this.timer = null
        }
    },
    generate: function() {   //生成方块
        let w = this.blocks.length - 1
        let p = parseInt(Math.random() * w, 10)
        return p
    },
    trans: function() {    //方块变形
        if (this.status != RUNNING) return;

        let shape = (this.shape + 1) % this.blocks[this.current].length
        let block = this.blocks[this.current][shape]
        if (this.position.left + block[0].length >= this.width) {
            this.position.left = this.width - block[0].length
        }
        for(let i = 0; i < block.length; i++) {
            for(let j = 0; j < block[i].length; j++) {
                if (block[i][j] > 0 && (this.position.top + i + 1 >= this.height || this.data[this.position.top + i][this.position.left + j] > 1)) {
                    return;
                }
            }
        }
        this.shape = shape
    },
    getBlock: function(block, shape) {
        return this.blocks[block][shape]
    },
    nextBlock: function() {  //下一方块
        let block = this.blocks[this.current][this.shape]
        for(let i = 0; i < block.length; i++) {
            for (let j = 0; j < block[i].length; j++) {
                if (block[i][j] > 0) {
                    this.data[this.position.top + i][this.position.left + j] = block[i][j]
                }
            }
        }
        this.clear()
        this.shape = 0
        this.current = this.next
        this.next = this.generate()
        this.position = {
            top: 0,
            left: 4,
        }
        this.checkOver()
    },
    clear: function() { //清除已满的行,计算分数和提速计算
        let len = 0;
        let h = this.height - 1
        while(h >= 0) {
            let full = true
            for(let j = 0; j < this.width; j++) {
                if (this.data[h][j] === 0) {
                    full = false
                    continue
                }
            }
            if (full) {
                len++
                for(let i = h - 1; i >= 0; i--) {
                    for (let j = 0; j < this.width; j++) {
                        this.data[i + 1][j] = this.data[i][j]
                    }
                }
            } else {
                h--
            }
        }
        if (len > 0) {
            this.score += len * 10
            if (this.score > this.lscore * this.speed) {
                this.speedUp()
            }
        }
    },
    speedUp: function() {   //升级加速
        if (this.speed >= this.maxSpeed) return;
        this.speed++;
        this.run();
    },
    checkOver: function() {
        let block = this.blocks[this.current][this.shape]
        for(let i = 0; i < block.length; i++) {
            for(let j = 0; j < block[i].length; j++) {
                if (block[i][j] > 0 && this.data[this.position.top + i][this.position.left + j] > 0) {
                    this.status = GAMEOVER
                    clearInterval(this.timer)
                    this.timer = null
                    return
                }
            }
        }
    },
    moveLeft: function() {  //左移
        if (this.status != RUNNING) return

        let block = this.blocks[this.current][this.shape]
        for(let i = 0; i < block.length; i++) {
            for (let j = 0; j < block[i].length; j++) {
                if (block[i][j] > 0 && (this.position.left - 1 + j < 0 || this.data[this.position.top + i][this.position.left - 1 + j] > 0)) {
                    console.log(block, this.position, i, j, this.data[this.position.top + i][this.position.left - 1 + j ])
                    return;
                }
            }
        }
        this.position.left--;
    },
    moveRight: function() { //右移
        if (this.status != RUNNING) return

        let block = this.blocks[this.current][this.shape]
        for(let i = 0; i < block.length; i++) {
            for (let j = block[i].length - 1; j >= 0; j--) {
                if (block[i][j] > 0 && (this.position.left + j + 1 >= this.width || this.data[this.position.top + i][this.position.left + j + 1] > 0)) {
                    return;
                }
            }
        }
        this.position.left++;
    },
    down: function() {  //下移
        if (this.status != RUNNING) return;
        let block = this.blocks[this.current][this.shape]
        for(let i = 0; i < block.length; i++) {
            for(let j = 0; j < block[i].length; j++) {
                if (block[i][j] > 0 && (this.position.top + i + 1 >= this.height || this.data[this.position.top + i + 1][this.position.left + j] > 0)) {
                    //无法下落转化
                    this.nextBlock()
                    return
                }
            }
        }
        this.position.top++;
    },
    render: function(){
        let data = []
        let block = this.getBlock(this.current, this.shape)
        for(let i = 0; i < this.data.length; i++) {
            let item = [];
            for (let j = 0; j < this.data[i].length; j++) {
                item.push(this.data[i][j])
            }
            data.push(item)
        }
        for (let i = 0; i < block.length; i++) {
            for (let j = 0; j < block[i].length; j++) {
                if (block[i][j] > 0) {
                    data[this.position.top + i][this.position.left + j] = block[i][j]
                }
            }
        }
        return data
    },
    run: function() {   //
        if (this.status != RUNNING) return;

        if (this.timer != null) {
            clearInterval(this.timer)
        }
        this.timer = setInterval(() => {
            this.down()
        }, (this.maxSpeed - this.speed + 1) * 200);
    }
}